package com.szu.subject.ui.controller;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.szu.subject.domains.College;
import com.szu.subject.domains.Comment;
import com.szu.subject.domains.Course;
import com.szu.subject.domains.CourseInfo;
import com.szu.subject.domains.Selection;
import com.szu.subject.domains.Student;
import com.szu.subject.domains.User;
import com.szu.subject.ui.mq.SendService;
import com.szu.subject.ui.service.CollegeService;
import com.szu.subject.ui.service.CommentService;
import com.szu.subject.ui.service.CourseService;
import com.szu.subject.ui.service.SelectionService;
import com.szu.subject.ui.service.StudentService;
import com.szu.subject.ui.service.UserService;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * controller层
 * 
 * @author ShenXiaolin
 *
 */
@RequestMapping("ui")
@RestController
public class UiController {
	
	@Autowired
	private CourseService courseService;
	
	@Autowired
	private StudentService studentService;
	
	@Autowired
	private UserService userService;
	
	@Autowired
	private CollegeService collegeService;
	
	@Autowired
	private CommentService commentService;
	
	@Autowired
	private SelectionService selectionService;
	

	@Resource
	private SendService sendService;
	private static Logger logger = LoggerFactory.getLogger(UiController.class);

	/**
	 * 获得所有的院系
	 * 
	 * @return
	 */
	@RequestMapping("get-all-college")
	public void getAllCollege(HttpServletRequest req, HttpServletResponse rep) throws Exception {
		
		List<College> list = collegeService.getAllColleges();
		JSONArray array = new JSONArray();
		for(int i=0;i<list.size();i++) {
			College college = list.get(i);			
			JSONObject json = JSONObject.fromObject(college);
			array.add(json);
		}
		rep.getWriter().print(array);
	}
	
	@RequestMapping("get-all-staffs")
	public List<User> getAllStaffs() {
		return userService.getAllUsers();
	}
	
	@RequestMapping("test")
	public String Test(){
		return "sdadas";
	}

	/**
	 * 获得某院系开设的所有课程
	 * 
	 * @param id
	 *            院系id
	 * @return
	 */
	@RequestMapping("get-courses-by-college")
	public ModelAndView getCourseByCollege(HttpServletRequest req, HttpServletResponse rep) {
		
		String collegeID = req.getParameter("collegeID");
		Long couID = Long.parseLong(collegeID);				
		List<Course> list = courseService.getCoursesByCollege(couID);
		College college = collegeService.getCollegeByPK(couID);
		
		ModelAndView mv = new ModelAndView();		
		mv.setViewName("table/tableCourseList");
		mv.addObject("list", list);
		mv.addObject("college", college);
		return mv;
	}

	/**
	 * 根据课程id获得该课程的评论
	 * 
	 * @param id
	 *            课程id
	 * @return
	 */
	@RequestMapping("get-course-comments")
	public List<Comment> getCommentByCourse(@RequestParam Long id) {
		return commentService.getCommentsByCourseId(id);
	}

	/**
	 * 根据课程id获得该课程最新的选课情况
	 * 
	 * @param id
	 *            课程id
	 * @return
	 */
	@RequestMapping("get-course-selection")
	public Map getSelection(@RequestParam Long id) {
		return  selectionService.getSelectionByCourseId(id);
	}

	/**
	 * 根据学生id获得该学生所选的所有课程
	 * 
	 * @param id
	 *            学生id
	 * @return
	 */
	@RequestMapping("get-courses-by-account")
	public List<Course> getCoursesByStudent(@RequestParam Long id) {
		return studentService.getCourses(id);
	}

	@RequestMapping("add-account-course-first")
	public int addCourseFirst(@RequestBody List<Course> courses) {
		Student student = (Student) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		List<Course> coursesList = student.getCourses();
		List<Course> coursesDistinct=courses.parallelStream().distinct().filter(c->!coursesList.contains(c)).filter(c->c.isTimeAvailable(coursesList)).collect(Collectors.toList());
		int length=coursesDistinct.size();
		List<Long> mark=new ArrayList<>(length);
		if(length>1){
			for(int i=1;i<=length;i++){
				Course course=coursesDistinct.get(i-1);
				if(course.isTimeAvailable(coursesDistinct, i)){
					mark.add(course.getId());
				}
			}
		}
		//去除时间重复。
		courses=coursesDistinct.parallelStream().filter(c->mark.contains(c.getId())).collect(Collectors.toList());
		CourseInfo courseInfo;
		List<CourseInfo> courseInfos = new ArrayList<>();
		for (Course course : courses) {
				courseInfo = new CourseInfo();
				courseInfo.setCourseId(course.getId());
				if (student.isMinorPrimary(course)) {
					courseInfo.setStudentType((short) 2);// 辅修
				} else if (student.isPrimary(course))
					courseInfo.setStudentType((short) 0);// 主选
				else {
					courseInfo.setStudentType((short) 1);// 非主选
				}
				courseInfo.setCourseType(course.getCourseType());
				courseInfo.setCredit(course.getCredit());
				courseInfo.setPrimaryLimit(course.getPrimaryUpperlimit());
				courseInfo.setSecondLimit(course.getSecondaryUpperlimit());
				courseInfos.add(courseInfo);
		}
		if (courseInfos.size() > 0) {
			Selection selection = new Selection();
			selection.setStudentId(student.getId());
			selection.setCredit(student.getStuCredit()-student.getHasCredit());
			selection.setCourseInfos(courseInfos);
			selection.setOperationType(true);
			sendService.sendFirst(selection);
		}
		return 0;
	}
	/**
	 * 第二轮选课
	 * 
	 * @param idMap
	 *            学生id和课程id
	 * @return
	 */
	@RequestMapping("add-account-course-second")
	public int addCourseSecond(@RequestBody List<Course> courses) {
//		Student student = (Student) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		Student student=studentService.getStudentByPK(2l);
		List<Course> coursesList = student.getCourses();
		//去重+过滤时间不允许的课程
		List<Course> coursesDistinct=courses.stream().distinct().filter(c->!coursesList.contains(c)).filter(c->c.isTimeAvailable(coursesList)).collect(Collectors.toList());
		coursesDistinct.parallelStream().map(Course::getId).forEach(System.out::println);
		int length=coursesDistinct.size();
		List<Long> mark=new ArrayList<>(length);
		if(length>1){
			for(int i=1;i<=length;i++){
				Course course=coursesDistinct.get(i-1);
				if(course.isTimeAvailable(coursesDistinct, i)){
					mark.add(course.getId());
				}
			}
		}
		logger.info("-------------------------------------------------");
		//去除时间重复。
		courses=coursesDistinct.parallelStream().filter(c->mark.contains(c.getId())).collect(Collectors.toList());
		courses.parallelStream().map(Course::getId).forEach(System.out::println);
		CourseInfo courseInfo;
		List<CourseInfo> courseInfos = new ArrayList<>();
		for (Course course : courses) {
				courseInfo = new CourseInfo();
				courseInfo.setCourseId(course.getId());
				if (student.isMinorPrimary(course)) {
					courseInfo.setStudentType((short) 2);// 辅修
				} else if (student.isPrimary(course))
					courseInfo.setStudentType((short) 0);// 主选
				else {
					courseInfo.setStudentType((short) 1);// 非主选
				}
				courseInfo.setCourseType(course.getCourseType());
				courseInfo.setPrimaryLimit(course.getPrimaryUpperlimit());
				courseInfo.setSecondLimit(course.getSecondaryUpperlimit());
				courseInfos.add(courseInfo);
		}
		if (courseInfos.size() > 0) {
			Selection selection = new Selection();
			selection.setStudentId(student.getId());
			selection.setCourseInfos(courseInfos);
			selection.setOperationType(true);
			sendService.sendSecond(selection);
		}
		
		return 0;
	}

	@RequestMapping("add-account-course-third")
	public int addCourseThird(@RequestBody List<Course> courses) {
		Student student = (Student) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		List<Course> coursesList = student.getCourses();
		List<Course> coursesDistinct=courses.parallelStream().distinct().filter(c->!coursesList.contains(c)).filter(c->c.isTimeAvailable(coursesList)).collect(Collectors.toList());
		int length=coursesDistinct.size();
		List<Long> mark=new ArrayList<>(length);
		if(length>1){
			for(int i=1;i<=length;i++){
				Course course=coursesDistinct.get(i-1);
				if(course.isTimeAvailable(coursesDistinct, i)){
					mark.add(course.getId());
				}
			}
		}
		//去除时间重复。
		courses=coursesDistinct.parallelStream().filter(c->mark.contains(c.getId())).collect(Collectors.toList());
		CourseInfo courseInfo;
		List<CourseInfo> courseInfos = new ArrayList<>();
		for (Course course : coursesDistinct) {
				courseInfo = new CourseInfo();
				courseInfo.setCourseId(course.getId());
				if (student.isMinorPrimary(course)) {
					courseInfo.setStudentType((short) 2);// 辅修
				} else if (student.isPrimary(course))
					courseInfo.setStudentType((short) 0);// 主选
				else {
					courseInfo.setStudentType((short) 1);// 非主选
				}
				courseInfo.setCourseType(course.getCourseType());
				courseInfo.setPrimaryLimit(course.getPrimaryUpperlimit());
				courseInfo.setSecondLimit(course.getSecondaryUpperlimit());
				courseInfos.add(courseInfo);
		}
		if (courseInfos.size() > 0) {
			Selection selection = new Selection();
			selection.setStudentId(student.getId());
			selection.setCourseInfos(courseInfos);
			selection.setOperationType(true);
			sendService.sendThird(selection);
		}
		return 0;
	}
	
	/**
	 * 退课
	 * 
	 * @param idMap
	 *            学生id和课程id
	 * @return
	 */
	@RequestMapping("remove-account-courses")
	public int removeCourses(@RequestBody List<Course> courses) {
		if(courses.size()<1){
			return 0;
		}
		CourseInfo courseInfo=new CourseInfo();
		Student student = (Student) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		List<CourseInfo> courseInfos = new ArrayList<>();
		for (Course course : courses) {
				courseInfo.setCourseId(course.getId());
				if (student.isMinorPrimary(course)) {
					courseInfo.setStudentType((short) 0);// 主选
				} else if (student.isPrimary(course))
					courseInfo.setStudentType((short) 1);// 主选
				else {
					courseInfo.setStudentType((short) 2);// 非主选
				}
				courseInfos.add(courseInfo);
		}
		Selection selection=new Selection();
		selection.setStudentId(student.getId());
		selection.setCourseInfos(courseInfos);
		selection.setOperationType(false);
		sendService.sendSecond(selection);
		return 0;
	}
	
	/**
	 * 移除多余的人数
	 */
	public void removeOverflow(){
		List<Course> courses=courseService.getAllCourses();
		List<CourseInfo> courseInfos=new ArrayList<>(courses.size());
		CourseInfo courseInfo=new CourseInfo();
		for(Course course:courses){
			courseInfo.setCourseId(course.getId());
			courseInfo.setPrimaryLimit(course.getPrimaryUpperlimit());
			courseInfo.setSecondLimit(course.getSecondaryUpperlimit());
			courseInfos.add(courseInfo);
		}
		selectionService.removeOverflow(courseInfos);
	}

	/**
	 * 根据课程id获得课程信息
	 * 
	 * @param id
	 *            课程id
	 * @return
	 */
	@RequestMapping("get-course-by-pk")
	public ModelAndView getCourseByPKTest(HttpServletRequest req, HttpServletResponse rep) {
		
		String courseID = req.getParameter("courseID");
		Long couID = Long.parseLong(courseID);				
		Course course = courseService.getByPK(couID);
		College college = collegeService.getCollegeByPK(course.getCollegeId());
		ModelAndView mv = new ModelAndView();		
		mv.setViewName("table/tableCourseDescription");
		mv.addObject("course", course);
		mv.addObject("college", college);
		return mv;
	}

	/*根据课程account获得课程信息*/
	@RequestMapping("get-course-by-account")
	public ModelAndView getCourseByAccount(HttpServletRequest req, HttpServletResponse rep) {
		
		String searchID = req.getParameter("searchID");
		System.out.println(searchID);
		Course course = courseService.getCourseByAccount(searchID);
		if(course==null) {
			System.out.println("null value!");
		}
		ModelAndView mv = new ModelAndView();		
		mv.setViewName("table/tableCourseSingle");
		mv.addObject("course", course);
		
		return mv;
	}

	/*根据课程名称-name-获得课程信息*/
	@RequestMapping("get-course-by-name")
	public ModelAndView getCourseByName(HttpServletRequest req, HttpServletResponse rep) {
		
		String searchName = req.getParameter("searchName");
		System.out.println(searchName);
		List<Course> list = courseService.getCourseByName(searchName);
		
		ModelAndView mv = new ModelAndView();		
		mv.setViewName("table/tableCourseList");
		mv.addObject("list", list);
		
		return mv;			
	}

	/*根据课程的开课老师名称获得课程信息*/
	@RequestMapping("get-course-by-teachername")
	public ModelAndView getCoursesByTeacherName(HttpServletRequest req, HttpServletResponse rep) {
		
		String searchName = req.getParameter("searchName");
		System.out.println(searchName);
		List<Course> list = courseService.getCoursesByTeacherName(searchName);
		
		ModelAndView mv = new ModelAndView();		
		mv.setViewName("table/tableCourseList");
		mv.addObject("list", list);
		
		return mv;	
	}

	/**
	 * 根据id获得学生的信息
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping("get-user-by-pk")
	public User getUserByPK(@RequestParam Long id) {
//		return accountHystrixSerivce.getByPK(id);
		return userService.getUserByPK(id);
	}

	// 获取用户的登录信息
	@RequestMapping("get-student-info")
	public void getStudentInfo(HttpServletRequest req, HttpServletResponse rep) throws Exception {
		req.setCharacterEncoding("utf-8"); // 这里不设置编码会有乱码
		rep.setContentType("text/html;charset=utf-8");
		rep.setHeader("Cache-Control", "no-cache");
		PrintWriter out = rep.getWriter();

		HttpSession httpsession = req.getSession();
		String sessionid = httpsession.getAttribute("loadid").toString();
		Long sLong = Long.parseLong(sessionid);
		Student student = studentService.getStudentByPK(sLong);
		System.out.println(student.getName());
		JSONObject json = JSONObject.fromObject(student);
		System.out.println(json);
		out.println(json);
	}

	// 用户登录确认
	@RequestMapping("checkload")
	public void checkLoad(HttpServletRequest req, HttpServletResponse rep) throws Exception {
		req.setCharacterEncoding("utf-8"); // 这里不设置编码会有乱码
		rep.setContentType("text/html;charset=utf-8");
		rep.setHeader("Cache-Control", "no-cache");
		PrintWriter out = rep.getWriter();
		String s = "y";
		
		// 获取文本框中的学号和密码
		String loadno = req.getParameter("loadno");
		String loadpass = req.getParameter("loadpass");
		// 获取验证码
		HttpSession httpsession = req.getSession();
		String sessioncheccknum = httpsession.getAttribute("randStr").toString();
		String checknum = req.getParameter("checknum");

		System.out.println(loadno + "--" + loadpass + "--" + checknum);

		Student student =studentService.getStudentByAccount(loadno);
		
		if (student == null){
			s = "学号错误,请重新输入";
			System.out.println(s);
			out.println(s);
		} else {
			String getuserpass = student.getPassword();
			if (loadpass.equals(getuserpass) && checknum.equals(sessioncheccknum)) {
				// 将获得的no && password存放到session中
				httpsession.setAttribute("loadid", student.getId());
				httpsession.setAttribute("loadno", loadno);
				httpsession.setAttribute("loadpass", loadpass);
				httpsession.setAttribute("loadname", student.getName());
				httpsession.setAttribute("credit", student.getStuCredit());
	
				s = "y";
				System.out.println(s);
				out.println(s);
			} else if (!loadpass.equals(getuserpass)) {
				s = "密码错误,请重新输入";
				System.out.println(s);
				out.println(s);
			} else if (!checknum.equals(sessioncheccknum)) {
				s = "验证码错误,请重新输入";
				System.out.println(s);
				out.println(s);
			}
		}
	}

	// 用户退出
	@RequestMapping("quitsys")
	public void quitSys(HttpServletRequest req, HttpServletResponse rep) throws Exception {
		req.setCharacterEncoding("utf-8"); // 这里不设置编码会有乱码

		rep.setContentType("text/html;charset=utf-8");
		rep.setHeader("Cache-Control", "no-cache");
		PrintWriter out = rep.getWriter();

		HttpSession hs = req.getSession();
		hs.invalidate();
		String s = "quit";

		System.out.println(s);
		out.println(s);
	}

	// 用户修改密码
	@RequestMapping("updatepassword")
	public void updatePassword(HttpServletRequest req, HttpServletResponse rep) throws Exception {
		req.setCharacterEncoding("utf-8"); // 这里不设置编码会有乱码
		rep.setContentType("text/html;charset=utf-8");
		rep.setHeader("Cache-Control", "no-cache");
		PrintWriter out = rep.getWriter();

		String s="y";

		// 获取文本框中的学号和密码
		String loadno = req.getParameter("loadno");
		String oldpassword = req.getParameter("oldpassword");
		String newpass = req.getParameter("newpassword");
		
		Student student = this.studentService.getStudentByAccount(loadno);
		if(student == null) {
			s = "学号错误,请重新输入";
			System.out.println(s);
			out.println(s);
		} else {
			if(student.getPassword().equals(oldpassword)) {
				student.setPassword(newpass);
				System.out.println(s);
				student = studentService.updateStudent(student);
				out.println(s);
			} else {
				s = "原始密码错误,请重新输入";
				System.out.println(s);
				out.println(s);
			}
		}
	}
	
	@RequestMapping("testpn/{id}")
	public Student testByPK(@PathVariable Long id){
		logger.info(id.toString());
		return studentService.getStudentByAccount(id.toString());
	}

}